package com.huawei.java.main.classes;

import java.util.HashMap;
import java.util.Map;

public class ServerInstance extends Server {
    private static int globalIndex = 0;
    private final int id;
    private final ServerNode aNode;
    private final ServerNode bNode;
    private final Map<Integer, Service> aliveService;
    private final Map<Integer, Boolean> deployInfo;

    protected ServerInstance(Server server) {
        super(server.getType(), server.getCpu(), server.getMemory(), server.getPrice(), server.getCost());
        this.id = globalIndex;
        aNode = new ServerNode(getCpu() / 2, getMemory() / 2);
        bNode = new ServerNode(getCpu() / 2, getMemory() / 2);
        aliveService = new HashMap<>();
        deployInfo = new HashMap<>();
        globalIndex++;
    }

    public void addService(Service service, int id, boolean deployA) {
        aliveService.put(id, service);
        if (service.isDoubleDeploy()) {
            deployInfo.put(id, null);
            aNode.add(service.getCpu() / 2, service.getMemory() / 2);
            bNode.add(service.getCpu() / 2, service.getMemory() / 2);
        } else {
            deployInfo.put(id, deployA);
            if (deployA) {
                aNode.add(service.getCpu(), service.getMemory());
            } else {
                bNode.add(service.getCpu(), service.getMemory());
            }
        }
    }

    public void delService(int id) {
        final Service service = aliveService.get(id);
        final Boolean deployA = deployInfo.get(id);
        aliveService.remove(id);
        deployInfo.remove(id);
        if (deployA == null) {
            aNode.del(service.getCpu() / 2, service.getMemory() / 2);
            bNode.del(service.getCpu() / 2, service.getMemory() / 2);
        } else if (deployA) {
            aNode.del(service.getCpu(), service.getMemory());
        } else {
            bNode.del(service.getCpu(), service.getMemory());
        }
    }

    public boolean fitService(Service service, boolean deployA) {
        final int cpu = service.getCpu();
        final int memory = service.getMemory();
        if (service.isDoubleDeploy()) {
            return aNode.getCurrentCpu() >= cpu / 2
                    && aNode.getCurrentMemory() >= memory / 2
                    && bNode.getCurrentCpu() >= cpu / 2
                    && bNode.getCurrentMemory() >= memory / 2;
        } else {
            if (deployA) {
                return aNode.getCurrentCpu() >= cpu
                        && aNode.getCurrentMemory() >= memory;
            } else {
                return bNode.getCurrentCpu() >= cpu
                        && bNode.getCurrentMemory() >= memory;
            }
        }
    }

    public int getId() {
        return id;
    }
}
